iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0

前言:昨天帶大家看了權重初始化的標準常態分佈,今天會帶大家介紹Glorot分佈,明天會解決梯度不穩定的問題。


程式碼的部分中我們需要在匯入套件的地方就先import glorot_normal和glorot_uniform這兩個權重初始化器,我們新增在註解處那行

from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense,Activation 
from tensorflow.keras.models import Sequential
from tensorflow.keras import optimizers
from tensorflow.keras.utils import plot_model
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.initializers import Zeros,RandomNormal,glorot_normal,glorot_uniform  #加入glorot_normal與glorot_uniform
import numpy as np
import matplotlib.pyplot as plt

glorot_normal() 常態分佈

接下來找到昨天設定權重初始值的地方,看大家要刪掉或是註解起來都可以,然後加入下面這一行,我們改用glorot常態分佈來設定權重初始值

w_init=glorot_normal()

我們可以看到跑出來的激活值分佈不那麼極端(畫出來的圖不一定會跟我的一樣,因為random()生成的亂數每次都不同)

https://ithelp.ithome.com.tw/upload/images/20231001/20161909auW3uZOro7.png

#完整程式碼
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense,Activation 
from tensorflow.keras.models import Sequential
from tensorflow.keras import optimizers
from tensorflow.keras.utils import plot_model
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.initializers import Zeros,RandomNormal,glorot_normal,glorot_uniform 
import numpy as np
import matplotlib.pyplot as plt

n_dense=256
n_input=784
b_init=Zeros()
w_init=glorot_normal()

model=Sequential()
model.add(Dense(n_dense,
                input_shape=(784,),
                kernel_initializer=w_init,
                bias_initializer=b_init)) 
model.add(Activation('sigmoid'))


x=np.random.random((1,n_input))
a=model.predict(x)

_=plt.hist(np.transpose(a))

glorot_uniform() 均勻分佈

另外一個常用的是w_init=glorot_uniform(),我們改寫在14行,不過這與Glorot_normal常態分佈沒有什麼明顯差異,但我們還是來做做看

from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense,Activation 
from tensorflow.keras.models import Sequential
from tensorflow.keras import optimizers
from tensorflow.keras.utils import plot_model
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.initializers import Zeros,RandomNormal,glorot_normal,glorot_uniform 
import numpy as np
import matplotlib.pyplot as plt

n_dense=256
n_input=784
b_init=Zeros()
w_init=glorot_uniform()

model=Sequential()
model.add(Dense(n_dense,
                input_shape=(784,),
                kernel_initializer=w_init,
                bias_initializer=b_init)) 
model.add(Activation('sigmoid'))


x=np.random.random((1,n_input))
a=model.predict(x)

_=plt.hist(np.transpose(a))

https://ithelp.ithome.com.tw/upload/images/20231001/20161909HdU7lHFf43.png


第18天我們提到當神經元使用某些激活函數(如Sigmoid或Tanh)時,它們在輸入值較高或較低(極端值)的情況下容易飽和,所以我們來試試看換成激活函數Tanh來看看激活值分佈吧!我們先用標準常態分佈來看,要修改的地方後面都有加上註解

from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense,Activation 
from tensorflow.keras.models import Sequential
from tensorflow.keras import optimizers
from tensorflow.keras.utils import plot_model
from tensorflow.keras.utils import to_categorical
from tensorflow.keras.initializers import Zeros,RandomNormal,glorot_normal,glorot_uniform 
import numpy as np
import matplotlib.pyplot as plt

n_dense=256
n_input=784
b_init=Zeros()
w_init=RandomNormal(stddev=1.0) #標準常態分佈

model=Sequential()
model.add(Dense(n_dense,
                input_shape=(784,), 
                kernel_initializer=w_init,
                bias_initializer=b_init)) 
model.add(Activation('tanh')) #激活函數tanh


x=np.random.random((1,n_input)) 
a=model.predict(x) 

_=plt.hist(np.transpose(a))

tanh搭配標準常態分佈初始化權重,可以發現產生的激活值也比較極端
https://ithelp.ithome.com.tw/upload/images/20231001/20161909Wr7lighXW2.png


我們把程式碼第14行改成w_init=glorot_normal #glorot常態分佈
https://ithelp.ithome.com.tw/upload/images/20231001/20161909oD95pgbJlG.png

總結:綜合以上結果,我們可以發現用glorot分佈下激活值分佈的平均且沒有極端值的出現,這樣有助於確保模型在訓練過程中更穩定地收斂,並且減少梯度消失或梯度爆炸的問題。而glorot分佈應該也是設定權重初始化目前最流行的用法之一


上一篇
權重初始化
下一篇
梯度不穩定(unstable gradient)&正規化
系列文
30天深度學習-從零到英雄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言